package com.dragon.protoJo.codec;

import com.dragon.protoJo.bean.msg.ProtoMsg;
import com.dragon.protoJo.ProtoInstant;
import com.sun.media.sound.InvalidFormatException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;


public class ProtobufDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
        // 标记一下当前的读指针位置
        in.markReaderIndex();
        //判断包头的长度
        if(in.readableBytes() < 8){
            // 不够包头
            return;
        }
        // 读取魔数
        short magic = in.readShort();
        if(magic != ProtoInstant.MAGIC_CODE){
            String error = "客户端口令不对：" + channelHandlerContext.channel().remoteAddress();
            throw new InvalidFormatException(error);
        }
        // 读取版本信息
        short version = in.readShort();

        // 读取发送过来的消息的长度
        int length = in.readShort();

        if(length < 0){
            // 非法数据，直接关闭连接
            channelHandlerContext.close();
        }

        if(length > in.readableBytes()){
            // 读取到的消息体长度如果小于发送过来的消息长度
            in.resetReaderIndex();
            return;
        }
        byte[] array;
        if (in.hasArray()){
            // 堆缓存
            ByteBuf slice = in.slice(in.readerIndex(),length);
            array = slice.array();
            in.retain();
        } else {
            // 直接缓冲
            array = new byte[length];
            in.readBytes(array,0,length);
        }
        // 字节转成对象
        ProtoMsg.Message outMsg = ProtoMsg.Message.parseFrom(array);
        if (in.hasArray()){
            in.release();
        }

        if(outMsg !=null){
            out.add(outMsg);
        }
    }
}
